﻿using System;
using System.Windows.Media;

namespace Red.Toolkit.Profiler.Logic
{
    /// <summary>
    /// Event node in a tree accelerating search, drawing and enabling block merging.
    /// </summary>
    public class EventNode
    {
        public Event Evt; // not null if leaf node
        public EventNode Left;
        public EventNode Right;
        public Color BlockColor;

        public double Start;
        public double End;
        public float weight;
        public Event.DrawStyle Style;
        public int TotalEvents;

        // create leaf node
        public EventNode( Event evt )
        {
            BlockColor = evt.Color;
            Style = evt.Style;
            Evt = evt;
            Left = Right = null;
            Start = evt.Evt.StartTime;
            End = evt.Evt.EndTime;
            weight = 1.0f;
            TotalEvents = 1;
        }

        // create internal node
        public EventNode( EventNode left, EventNode right )
        {
            Evt = null;
            Style = Event.CombineDrawStyles( left.Style, right.Style );
            Left = left;
            Right = right;
            Start = Math.Min( left.Start, right.Start );
            End = Math.Max( left.End, right.End );

            double weigthA = (left.End - left.Start) * left.weight;
            double weightB = (right.End - right.Start) * right.weight;
            BlockColor = Core.ColorHelpers.InterpolateColors( left.BlockColor, right.BlockColor,
                (float)weightB / (float)(weigthA + weightB) );

            weight = (float)weigthA;
            weight += (float)weightB;
            weight /= (float)(End - Start);
            weight = Math.Max( 0.0f, Math.Min( 1.0f, weight ) );

            TotalEvents = left.TotalEvents + right.TotalEvents;
        }

        // update IsSelected flag based on children status
        public void UpdateSelectionRecursive()
        {
            if ( Evt != null )
                Style = Evt.Style;
            else
            {
                Left.UpdateSelectionRecursive();
                Right.UpdateSelectionRecursive();
                Style = Event.CombineDrawStyles( Left.Style, Right.Style );
            }
        }
    }
}
